package cn.tedu.csmall.stock.webapi.controller;

import cn.tedu.csmall.commons.exception.CoolSharkServiceException;
import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall.commons.restful.JsonResult;
import cn.tedu.csmall.commons.restful.ResponseCode;
import cn.tedu.csmall.stock.service.IStockService;
import cn.tedu.csmall.stock.webapi.exception.StockBlockError;
import cn.tedu.csmall.stock.webapi.exception.StockFallbackError;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Api(tags = "库存模块")
@RequestMapping("/base/stock")
public class StockController {
    @Autowired
    private IStockService stockService;


    @PostMapping("/reduce/count")
    @ApiOperation("减少商品库存")
    //添加该注解，该方法就会被sentinel管理
    //blockHandler属性是指定的就是限流方法名
    //fallback属性是指定的就是降级方法名
    @SentinelResource(value = "减少库存",
            blockHandlerClass = StockBlockError.class,blockHandler = "blockError",
            fallbackClass = StockFallbackError.class,fallback = "fallbackError")
    public JsonResult reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO){
        //为了出现降级，模拟请求处理失败，百分之80的概率，抛出异常
        if(Math.random()<0.8){
            throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"抛出随机异常");
        }
        stockService.reduceStockByCommodityCode(stockReduceCountDTO);
        return JsonResult.ok("减少商品库存完成！");
    }

    //实现自定义限流方法
    /*
      1.访问修饰符是public类型
      2.返回值类型需要和被限流的方法保持一致
      3.方法名是blockHandler属性的属性值
      4.参数列表需要和被限流的方法中的参数列表保持一致，除此之外还需要添加一个BlockException类型的参数
     */
/*    public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO, BlockException blockException){
        //限流方法一般直接返回限流信息就可以了
        return JsonResult.failed(ResponseCode.BAD_REQUEST,"服务器繁忙，请稍后重试~");
    }*/
    //实现自定义降级方法
    /*
      1.访问修饰符是public类型
      2.返回值类型需要和被限流的方法保持一致
      3.方法名是fallbackHandler属性的属性值
      4.参数列表需要和被限流的方法中的参数列表保持一致，还可以添加一个异常的参数类型
     */
   /* public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO){
        //降级代码中可以返回提示信息，也可以返回缓存的内容等等
        return JsonResult.failed(ResponseCode.BAD_REQUEST,"请求超时，请重试~");
    }*/
}
